iT邦幫忙

2025 iThome 鐵人賽

DAY 25
0
Modern Web

現在就學Node.js系列 第 25

RBAC 角色權限控管 - Day 25

  • 分享至 

  • xImage
  •  

為什麼要有 RBAC?

隨著系統成長,權限管理會漸漸失控。

一開始或許只是幾個簡單的判斷式:

if (user.isAdmin) { ... }
if (user.permission.includes("deletePost")) { ... }

但當功能越來越多、角色越來越複雜。

結果是:

  • 改一個角色,牽一發動全身
  • 權限散落在各個檔案中,難以追蹤
  • 新人加入團隊時完全搞不清楚誰能做什麼

RBAC(Role-Based Access Control,角色基礎存取控制)

正是為了解決這個問題而誕生的架構。

它將權限管理「結構化、模組化」,

讓程式乾淨、邏輯一致,並且能隨需求成長。

RBAC 的核心理念

RBAC 的核心邏輯:

使用者(User)不直接擁有權限,而是透過角色(Role)間接取得權限(Permission)。

換句話說,你不用在每個人身上設定權限,

而是設定角色 → 然後把使用者指派到角色。

User → Role → Permission
  • User(使用者):登入系統的帳號。
  • Role(角色):代表一種職責或身份,例如「管理員」「編輯者」「訪客」。
  • Permission(權限):系統中可執行的具體行為,例如「新增文章」「刪除留言」。

這樣的架構設計有兩大優點:

  1. 靈活調整:要新增權限?改角色,不用動程式。
  2. 稽核:可以清楚追蹤「誰透過哪個角色擁有哪個權限」。

RBAC 的三個實務層面

RBAC 並不只是後端的概念,而是在整個系統中的權限管控。

1️⃣ 功能層(Feature-Level Access)

解決:「能不能做」的問題。

最直接的 RBAC 用法:

控制某個角色能否呼叫某個 API、使用某個功能。

角色 可執行功能
Admin 建立/編輯/刪除使用者
Editor 新增/修改文章
Viewer 僅可瀏覽

後端通常透過 Middleware 來檢查:

router.post("/posts", verifyToken, authorizeRoles("editor", "admin"), createPost);

✅ 有權限 → 放行

🚫 沒權限 → 回傳 403 Forbidden

2️⃣ 資料層(Data-Level Access)

解決:「能看到多少」的問題。

登入不代表可以看全部資料。

我們常需根據角色決定資料範圍:

  • 銷售員 → 只能看自己的客戶
  • 區域主管 → 看該區域所有客戶
  • 管理員 → 看全部

實作上,就是在查詢時加入條件限制:

const posts = await Post.find({ authorId: req.user.id });

RBAC 不只管「能不能用哪些功能」,還可管「能看到哪些資料」。

3️⃣ 畫面層(UI-Level Access)

解決:「要不要顯示」的問題。

前端也該尊重權限設定。

讓不同角色看到不同畫面,能有效防止誤操作。

角色 顯示畫面
Admin 使用者管理按鈕
Editor 發表文章按鈕
Viewer 只讀畫面

但要記得:

即使前端隱藏按鈕,後端仍要驗證。

真正的授權判斷必須在伺服器端完成。

RBAC 的資料結構設計

RBAC 通常可分成五張主要資料表(或集合):

Collection 說明
users 使用者資料
roles 角色定義(admin/editor/viewer)
permissions 權限定義(如 createPost、deleteUser)
user_roles 使用者與角色關聯
role_permissions 角色與權限關聯

這樣的設計能達到:

  • 易維護:新增角色不動程式。
  • 易稽核:權限清楚明確。
  • 易擴充:能支援部門、組織層級。

💾 MongoDB 實例示意

// User
{
  "_id": "u01",
  "username": "alice",
  "roles": ["editor"]
}

// Role
{
  "_id": "r01",
  "name": "editor",
  "permissions": ["create:post", "edit:post"]
}

// Permission
{
  "_id": "p01",
  "name": "create:post"
}

實際查詢流程:

const user = await User.findOne({ username: "alice" }).populate("roles");
const role = await Role.findOne({ name: user.roles[0] });
if (role.permissions.includes("create:post")) {
  // ✅ 有權限,放行
}

RBAC 的優勢

優點 說明
結構清晰 權限集中管理,不再散落程式各處
容易維護 調整角色或權限不需改程式碼
高安全性 落實最小權限原則(Least Privilege)
可稽核性強 可追蹤誰擁有什麼權限
與 JWT 結合自然 Token 可攜帶角色資訊,API 驗證快速輕量

小結:

RBAC 的核心價值不只是「多幾個角色」,

而是讓整個系統擁有可觀察、可維護、可審計的權限結構

它能夠讓你的系統做到:

1️⃣ 誰可以執行什麼功能?(功能層)

2️⃣ 誰可以看到哪些資料?(資料層)

3️⃣ 誰應該看到哪些畫面?(介面層)

今天有了基礎的RBA概念後,明日我們就來運用這概念搭配上API的實作吧!


上一篇
JWT Refresh Token 自動延長機制 - Day24
系列文
現在就學Node.js25
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言